package ch.il07.converter.persistance.tests;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;

import org.junit.Before;
import org.junit.Test;

import ch.il07.converter.persistence.Persistence;
import ch.il07.converter.persistence.PersistenceHelper;
import ch.il07.converter.persistence.entities.AccessLevel;
import ch.il07.converter.persistence.entities.Measurand;
import ch.il07.converter.persistence.entities.Unit;
import ch.il07.converter.persistence.entities.User;
import ch.il07.converter.persistence.exceptions.AlreadyDefinedException;
import ch.il07.converter.persistence.exceptions.PersistenceException;
import ch.il07.converter.persistence.exceptions.UserAlreadyExistsException;
import ch.il07.utils.RandomHelper;

public class Nominate {

	private Persistence persistence;

	@Before
	public void setUp() {
		try {
			persistence = PersistenceHelper.getPersistence();
		} catch (PersistenceException e) {
			fail(e.getMessage());
		}
	}

	@Test
	public void nominateMeasurand() {

		// Add User
		User u = null;
		try {
			String username = RandomHelper.randString();
			persistence.addUser(username, RandomHelper.getEmail(username),
					username, AccessLevel.USER);
			u = persistence.getUser(username, username);
			assertNotNull("User does not exist", u);
		} catch (UserAlreadyExistsException e) {
			e.printStackTrace();
		} catch (PersistenceException e) {
			e.printStackTrace();
		}

		// Add Measurand

		String mName = RandomHelper.randString();
		Measurand m = new Measurand(mName, new Unit(RandomHelper.randString(),
				1D));
		m.setOwner(u);

		{
			try {
				persistence.addMeasurand(m, u.getUsername());
			} catch (AlreadyDefinedException e) {
				e.printStackTrace();
				fail(e.getMessage());
			} catch (PersistenceException e) {
				e.printStackTrace();
				fail(e.getMessage());
			}
		}

		// Add Nomination

		try {
			persistence.nominate(u, m);
		} catch (PersistenceException e) {
			e.printStackTrace();
			fail(e.getMessage());
		}

		// Test Nomination

		try {
			List<Measurand> measurands = persistence.getAllNominatedMeasurands();
			boolean success = false;
			for (Measurand measurand : measurands) {
				if (measurand.getName().equals(m.getName())) {
					success = true;
				}
			}

			assertTrue("Nomination not found", success);

		} catch (PersistenceException e) {
			e.printStackTrace();
			fail(e.getMessage());
		}

	}

	@Test
	public void nominateUnit() {

		// Add User
		User u = null;
		try {
			String username = RandomHelper.randString();
			persistence.addUser(username, RandomHelper.getEmail(username),
					username, AccessLevel.USER);
			u = persistence.getUser(username, username);
		} catch (UserAlreadyExistsException e) {
			e.printStackTrace();
		} catch (PersistenceException e) {
			e.printStackTrace();
		}

		// Add Measurand

		String mName = RandomHelper.randString();
		Measurand m = new Measurand(mName, new Unit(RandomHelper.randString(),
				1D));

		{
			try {
				persistence.addMeasurand(m, u.getUsername());
			} catch (AlreadyDefinedException e) {
				fail(e.getMessage());
				e.printStackTrace();
			} catch (PersistenceException e) {
				fail(e.getMessage());
				e.printStackTrace();
			}
		}

		// Add Unit

		Unit un = new Unit(RandomHelper.randString(), 12D);

		try {
			persistence.addUnit(m, un);
		} catch (AlreadyDefinedException e1) {
			e1.printStackTrace();
		} catch (PersistenceException e1) {
			e1.printStackTrace();
		}

		// Add Nomination
		try {
			persistence.nominate(u, m, un);
			List<Unit> nominatedUnits = persistence.getAllNominatedUnits();
			boolean success = false;
			for (Unit unit : nominatedUnits) {
				if (unit.getUnitId().equals(un.getUnitId())) {
					success = true;
					break;
				}
			}
			assertTrue("Add Nomination Failed", success);

		} catch (PersistenceException e) {
			e.printStackTrace();
		}

	}

}
